import { JXDef } from "../../conventions/JXCommon";
import { INVALID_VALUE } from "../../Core/CoreDefine";
import { ObjectWrap } from "../../Core/FrameEx/ES5Ex";
import GTimerMgr from "../../Core/Manager/GTimerMgr";
import { RedPointLogicMgr } from "../../Core/Manager/RedPointLogicMgr";
import { UIMgr } from "../../Core/Manager/UIMgr";
import { CHECK_TIME, LoadingType } from "../Common/Define";
import { VIEW_ID } from "../Common/UI";
import LHeroData from "../Data/Locals/LHeroData";
import LOwnEquips from "../Data/Locals/LOwnEquips";
import LOwnItems from "../Data/Locals/LOwnItems";
import { LUserData } from "../Data/Locals/LUserData";
import RBagData from "../Data/RunTime/RBagData";
import { RUserData } from "../Data/RunTime/RUserData";
import { SAction } from "../Data/Static/SAction";
import { SActionCollision } from "../Data/Static/SActionCollision";
import { SAddDialData } from "../Data/Static/SAddDialData";
import { SBuffData } from "../Data/Static/SBuffData";
import { SBullet } from "../Data/Static/SBullet";
import { SCallData } from "../Data/Static/SCallData";
import { SDialData } from "../Data/Static/SDialData";
import { SEffectAnim } from "../Data/Static/SEffectAnim";
import { SEquipData } from "../Data/Static/SEquipData";
import { SGuideChainData } from "../Data/Static/SGuideChainData";
import { SGuideStepData } from "../Data/Static/SGuideStepData";
import { SHeroData } from "../Data/Static/SHeroData";
import { SHeroTryData } from "../Data/Static/SHeroTryData";
import { SItemData } from "../Data/Static/SItemData";
import { SLvData } from "../Data/Static/SLvData";
import { SNoticeData } from "../Data/Static/SNoticeData";
import { SNpcTeamData } from "../Data/Static/SNpcTeamData";
import { SOfficerData } from "../Data/Static/SOfficerData";
import { SOnLineAwardData } from "../Data/Static/SOnLineAwardData";
import { SScopeData } from "../Data/Static/SScopeData";
import { SSignInData } from "../Data/Static/SSignInData";
import { SSkillData } from "../Data/Static/SSkillData";
import { SSkillEffect } from "../Data/Static/SSkillEffect";
import { SStarLvData } from "../Data/Static/SStarLvData";
import { SStoryData } from "../Data/Static/SStoryData";
import { SSuitData } from "../Data/Static/SSuitData";
import { STowerData } from "../Data/Static/STowerData";
import { SUnitData } from "../Data/Static/SUnitData";
import { SVipData } from "../Data/Static/SVipData";
import JumpToMgr from "../Views/ViewUtil/JumpUtil";
import { GCtrl } from './../../Core/GCtrl';
import { DataPool } from './../../Core/Manager/DataPool';
import { RHeroData } from './../Data/RunTime/RHeroData';
import { SLvUpData } from './../Data/Static/SLvUpData';
import { SMapData } from './../Data/Static/SMapData';
import { SMapStyleData } from './../Data/Static/SMapStyleData';
import { SSystemConfig } from './../Data/Static/SSystemConfig';
import { GuideLogic } from './../Guide/GuideLogic';
import { HeroMgr } from "./HeroMgr";
import ItemMgr from "./ItemMgr";
import MapMgr from "./MapMgr";
import SdkMgr from "./SdkMgr";
import UserMgr from "./UserMgr";



/**
 * 1. 项目调试环境     WD_DEBUG     构建中wdDebug = true
 * 2. 全局控制器       jx               CC_DEV|| CC_DEBUG , 且 WD_DEBUG
 * 3. 物品代码                         CC_DEV || CC_DEBUG , 且 WD_DEBUG;
 * 4. GM指令                          CC_DEV || CC_DEBUG
 * 5. 模拟充值                         GM指令开启，对应SDK没有重载支付接口
 * 6. 充值入口                         IOS不可支付(以及去除)，其他的通过GameEnv参数决定
 * 7. 分享接口                         根据SDK提供的canSdkShare函数的返回值决定
 */

export default class GameMgr extends ObjectWrap {
    protected static _ins: GameMgr;
    public static ins(): GameMgr {
        if (!this._ins) {
            this._ins = new GameMgr;
        }
        return this._ins;
    }
    /** 热数据 */
    public static rHeroData: RHeroData = null;
    public static RBagData: RBagData;
    public static rUserData: RUserData = null;
    /** 静态数据 */
    /**VIP表 */
    public static vipData: SVipData = null;
    public static mapData: SMapData = null;
    public static mapStyle: SMapStyleData = null;
    //在线时长
    public static onLineAwardData: SOnLineAwardData = null;
    /**装备表 */
    public static noticeData: SNoticeData = null;
    public static suitData: SSuitData = null;
    public static equipData: SEquipData = null;
    public static action: SAction = null;
    public static actionCollision: SActionCollision = null;
    public static buffData: SBuffData = null;
    public static bullet: SBullet = null;
    public static dialData: SDialData = null;
    public static effectAnim: SEffectAnim = null;
    public static heroData: SHeroData = null;
    public static itemData: SItemData = null;
    public static npcTeamData: SNpcTeamData = null;;
    public static signInData: SSignInData = null;
    public static skillEffect: SSkillEffect = null;
    public static storyData: SStoryData = null;
    public static unitData: SUnitData = null;
    public static skillData: SSkillData = null;
    public static systemConfig: SSystemConfig = null;
    public static officerData: SOfficerData = null;
    public static scopeData: SScopeData = null;
    public static lvData: SLvData = null;
    public static lvUpData: SLvUpData = null;
    public static starLvData: SStarLvData = null;
    public static towerData: STowerData = null;
    public static guideChainData: SGuideChainData = null;
    public static guideStepData: SGuideStepData = null;
    public static heroTryData: SHeroTryData = null;
    public static callData: SCallData = null;
    public static addDialData: SAddDialData = null;
    /** 本地数据 */
    public static lUserData: LUserData = null;
    public static lHeroData: LHeroData = null;
    public static lOwnItems: LOwnItems;
    public static lOwnEquips: LOwnEquips;
    /** 引导管理器 */
    public static guideMgr: GuideLogic = null
    /** 管理器 */
    /** 跳转管理器 */
    public static jumpToMgr: JumpToMgr = null
    public static sdkMgr: SdkMgr = null;
    public static mapMgr: MapMgr = null;
    public static userMgr: UserMgr = null;
    public static heroMgr: HeroMgr = null;
    public static itemMgr: ItemMgr = null;
    /** UI管理器 */
    public static uiMgr = UIMgr;
    public static redMgr: RedPointLogicMgr = null;
    /**当前渠道 */
    /** 时间调度容器 */
    protected _timeCounters: GameTimer[] = [];
    /** 定时闹钟管理器 */
    protected _timeColocks: GameTimeClock[] = [];
    protected _timeIndex: number;
    /** 耗时任务去重（如果短时间内出现同一个任务则，不发送） */
    protected _lastEndTaskId: string = null;
    /** 军队任务去重（如果端时间内出现同一个任务则不发送 */
    public lastEndArmyTaskId: string = null;

    ///////////////////////////////////////////////Init Functions////////////////////////////////////////////////////////////////////////////
    // 加载i18n客户端表格数据
    protected static __STATIC_CONFIG_INIT() {
        window.wdStatics = {
            locales: [],
            launchFiles: [],
            allFiles: [
                "vipData", "mapData", "mapStyleData", 'equipData', 'action', 'actionCollision', 'buffData', 'bullet', 'effectAnim', 'heroData', 'itemData', 'suitData',
                'npcTeamData', 'signInData', 'skillEffect', 'storyData', 'unitData', "skillData", "systemConfig", 'officerData', 'scopeData', 'lvData', 'lvUpData', 'starLvData', 'dialData',
                'towerData', "guideChainData", "guideStepData", "onLineAwardData", "noticeData", "heroTryData", "callData", "addDialData"
            ]
        };
        window.wdStatics.locales = window.wdStatics.locales.map((v, k) => "" + v);
        window.wdStatics.launchFiles = window.wdStatics.launchFiles.map((v, k) => "" + v);
        window.wdStatics.allFiles = window.wdStatics.allFiles.map((v, k) => "" + v);
        window.wdStatics.loadStatus = window.wdStatics.loadStatus || {};
    }

    /** 初始化客户端登陆的时候需要的静态数据 */
    public static initLoginStatic(progress: ProgressCallback<any>, callBack: CompleteCallback<any>) {
        this.__STATIC_CONFIG_INIT();
        let onLoadEnd = () => {
            callBack();
        }

        let fileNames = window.wdStatics.launchFiles;
        DataPool.ins().loadRTStatics(fileNames, (fileName: string, cur: number, total: number) => {
            window.wdStatics.loadStatus[fileName] = true;
            progress && progress(cur, fileNames.length);
        }, () => onLoadEnd());
    }

    // 初始化客户端登陆的时候需要的运热数据
    public static onInitLoginRunTime() {
    }

    // 通用结束接口
    protected static _commonStaticsLoadEnd() {
        this.vipData = DataPool.ins().getStatic(SVipData);
        this.mapData = DataPool.ins().getStatic(SMapData);
        this.mapStyle = DataPool.ins().getStatic(SMapStyleData);
        this.lvUpData = DataPool.ins().getStatic(SLvUpData);
        this.starLvData = DataPool.ins().getStatic(SStarLvData);
        this.towerData = DataPool.ins().getStatic(STowerData);
        this.equipData = DataPool.ins().getStatic(SEquipData);
        this.suitData = DataPool.ins().getStatic(SSuitData);
        this.noticeData = DataPool.ins().getStatic(SNoticeData);
        this.action = DataPool.ins().getStatic(SAction);
        this.actionCollision = DataPool.ins().getStatic(SActionCollision);
        this.buffData = DataPool.ins().getStatic(SBuffData);
        this.bullet = DataPool.ins().getStatic(SBullet);
        this.dialData = DataPool.ins().getStatic(SDialData);
        this.effectAnim = DataPool.ins().getStatic(SEffectAnim);
        this.heroData = DataPool.ins().getStatic(SHeroData);
        this.itemData = DataPool.ins().getStatic(SItemData);
        this.npcTeamData = DataPool.ins().getStatic(SNpcTeamData);
        this.signInData = DataPool.ins().getStatic(SSignInData);
        this.skillEffect = DataPool.ins().getStatic(SSkillEffect);
        this.storyData = DataPool.ins().getStatic(SStoryData);
        this.unitData = DataPool.ins().getStatic(SUnitData);
        this.skillData = DataPool.ins().getStatic(SSkillData);
        this.systemConfig = DataPool.ins().getStatic(SSystemConfig);
        this.officerData = DataPool.ins().getStatic(SOfficerData);
        this.scopeData = DataPool.ins().getStatic(SScopeData);
        this.lvData = DataPool.ins().getStatic(SLvData);
        this.guideChainData = DataPool.ins().getStatic(SGuideChainData);
        this.guideStepData = DataPool.ins().getStatic(SGuideStepData);
        this.onLineAwardData = DataPool.ins().getStatic(SOnLineAwardData);
        this.heroTryData = DataPool.ins().getStatic(SHeroTryData);
        this.callData = DataPool.ins().getStatic(SCallData);
        this.addDialData = DataPool.ins().getStatic(SAddDialData);
    }

    /** 初始化 */
    public static initFristGameStatics(progress: ProgressCallback<any>, callBack: CompleteCallback<any>) {
        DataPool.ins().loadRTStatics(window.wdStatics.allFiles, (fileName: string, cur: number, total: number) => {
            window.wdStatics.loadStatus[fileName] = true;
            progress && progress(cur, window.wdStatics.allFiles.length);
        }, () => {
            this._commonStaticsLoadEnd();
            GameMgr.initLocalData();
            GameMgr.initGameRunTime();
            callBack();
        })
    }



    public static initAllStatics(progress: ProgressCallback<any>, callBack: CompleteCallback<any>) {
        this.__STATIC_CONFIG_INIT();
        let table = window.wdStatics.allFiles;
        for (let i = 0; i < window.wdStatics.launchFiles.length; i++) {
            if (table.indexOf(window.wdStatics.launchFiles[i]) != INVALID_VALUE) {
                continue;
            }
            table.push(...window.wdStatics.launchFiles);
        }

        DataPool.ins().loadRTStatics(table, (fileName: string, cur: number, total: number) => {
            window.wdStatics.loadStatus[fileName] = true;
            progress && progress(cur, table.length);
        }, () => {
            this._commonStaticsLoadEnd();
            GameMgr.initLocalData();
            GameMgr.initGameRunTime();
            callBack();
        })
    }

    /** 初始化客户端游戏进行时需要的热数据 */
    public static initGameRunTime() {
        this.RBagData = DataPool.ins().getRunTime(RBagData);
        this.rHeroData = DataPool.ins().getRunTime(RHeroData);
        this.rUserData = DataPool.ins().getRunTime(RUserData);
    }

    /**初始化本地数据 */
    public static initLocalData() {
        this.lUserData = DataPool.ins().getLocal(LUserData);
        this.lHeroData = DataPool.ins().getLocal(LHeroData);
        this.lOwnEquips = DataPool.ins().getLocal(LOwnEquips);
        this.lOwnItems = DataPool.ins().getLocal(LOwnItems);
    }

    /** 初始化逻辑管理器 */
    public static initLogicManager() {
        this.redMgr = RedPointLogicMgr.ins();
        this.guideMgr = GuideLogic.ins();
        this.userMgr = UserMgr.ins();
        this.heroMgr = HeroMgr.ins();
        this.itemMgr = ItemMgr.ins;
        this.sdkMgr = SdkMgr.ins;
        this.mapMgr = MapMgr.ins;
    }

    public static initSimulator() {
        this.jumpToMgr = JumpToMgr.ins;
    }

    public initReConnectEvent() {

    }

    public initGame() {
        GCtrl.ES.on(GCtrl.GTimerSecondEventMsg, this, this.onTimeCalculat.bind(this));
        let now = GCtrl.now;
        this._timeCounters = [
            { delta: 0, checkTime: CHECK_TIME.TIME_CLOCK_CHECK, outTimeHandler: GameMgr.redMgr.timingCheck.bind(GameMgr.redMgr) }
        ];
        GTimerMgr.ins().start();
        //底层功能
        // 二级
        GameMgr.jumpToMgr.initGame();
        GameMgr.sdkMgr.initGame();
        // 三级: 综合管理器要放到其他功能模块的管理器后面，因为会有引用
        GameMgr.guideMgr.initGame()
        GameMgr.redMgr.initGame();
    }

    public onReconnect() {

    }

    public static clearRunTime() {
        DataPool.ins().clearRunTimes();
    }
    public static clearLoacalData() {
        DataPool.ins().clearLocals();
    }
    public restart() {
        // 注销事件
        GCtrl.ES.off(this);
        // 注销事件
        GCtrl.ES.off(this);
        GameMgr.jumpToMgr.loginOut();
        GameMgr.sdkMgr.loginOut();
        GameMgr.guideMgr.loginOut();
        GameMgr.redMgr.loginOut();
        for (const key in JXDef.LOCAL_KEY) {
            cc.sys.localStorage.removeItem(JXDef.LOCAL_KEY[key]);
        }
        GameMgr.clearRunTime();
        GameMgr.clearLoacalData();
        let GuideRoot = GameMgr.uiMgr.uiRoot.parent.getChildByName("GudieRoot");
        if (GuideRoot) { GuideRoot.destroy() }
        let topPannel = GameMgr.uiMgr.uiRoot.getChildByName("TopUiItem");
        if (topPannel) {
            topPannel.destroy();
        }
        // 移除所有界面
        UIMgr.removeAllActiveWin();
        UIMgr.showWin(VIEW_ID.load, LoadingType.AppStart);
    }


    /////////////////////////////////////////////////////////////////////////////////////////////////
    public onTimeCalculat() {
        this._timeCounters.forEach(e => e.delta += GCtrl.deltaSecondTime);
        // 性能优化，保证一帧最多处理一个事件
        this._timeIndex = this._timeIndex || 0;
        if (this._timeIndex >= this._timeCounters.length) {
            // 一次轮回清理一起当前记录的耗时任务
            this._lastEndTaskId = null;
            this.lastEndArmyTaskId = null;
            this._timeIndex = 0;
        }

        let timer = this._timeCounters[this._timeIndex];
        if (timer.delta >= timer.checkTime) {
            timer.outTimeHandler(timer.delta);
            timer.delta = 0;
        }
        this._timeIndex++;
    }


}

